﻿using AntMovement.Core;
using AntMovement.Core.Model;
using AntMovement.Model;
using AntMovement.WPF.Attributes;
using AntMovement.WPF.Model;
using MaterialDesignThemes.Wpf;
using Prism.Commands;
using Prism.Events;
using Prism.Ioc;
using Prism.Modularity;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace AntMovement.ViewModels
{
    public class EnumTreeViewModel
    {
        private List<MenuAssemblyModel> menuAssemblyModels = new List<MenuAssemblyModel>();
        public ObservableCollection<AntMovement.WPF.Model.MenuModel> Menus { get; set; }
        private IEventAggregator _aggregator;
        private IContainerExtension _containerExtension;
        public EnumTreeViewModel(IContainerExtension containerExtension, IEventAggregator aggregator)
        {
            _containerExtension = containerExtension;
            _aggregator = aggregator;
            Menus = new ObservableCollection<WPF.Model.MenuModel>();
            Init();
            UpdateMenu();
            DisplayFirstView(true);

        }
        private void DisplayFirstView(bool isOne = true)
        {
            if (Menus.Count > 0 && Menus[0].Childrens.Count > 0)
            {
                OpenView(Menus[0].Childrens[0], isOne);
            }
        }

        private object _oldView;
        private void OpenView(MenuItemModel menu, bool isOne = true)
        {
            try
            {
                if (menu != null && menu.View != null && menu.ViewModel != null)
                {
                    if (_oldView is System.Windows.Controls.UserControl user && user.DataContext is IViewModelLife life)
                    {
                        try
                        {
                            life.Exit();
                        }
                        catch (Exception ex)
                        {
                            _containerExtension.Resolve<IDialogHost>()?.DialogShow($"{menu.ViewModel.Name}视图退出事件异常：{ex}", Core.Enum.LogLevel.Warning);
                        }
                    }
                    UserControl userControl = Activator.CreateInstance(menu.View) as System.Windows.Controls.UserControl;
                    List<object> plist = new();
                    var ps = menu.ViewModel.GetConstructors()[^1].GetParameters();
                    foreach (var p in ps)
                    {
                        plist.Add(_containerExtension.Resolve(p.ParameterType));
                    }
                    userControl.DataContext = Activator.CreateInstance(menu.ViewModel, plist.ToArray());
                    try
                    {
                        if (userControl.DataContext is IViewModelLife life1)
                        {
                            life1.Enter();
                        }
                    }
                    catch (Exception ex)
                    {
                        _containerExtension.Resolve<IDialogHost>()?.DialogShow($"{menu.ViewModel.Name}视图进入事件异常：{ex}", Core.Enum.LogLevel.Warning);
                    }
                    _oldView = userControl;
                    MessageEventModel message = new MessageEventModel
                    {
                        Code = 200,
                        Message = "View",
                        Data = new Dictionary<string, object>() { { "View", userControl } }
                    };
                    _aggregator.GetEvent<MessageEvent>().Publish(message);
                }
            }
            catch (Exception ex)
            {
                _containerExtension.Resolve<IDialogHost>()?.DialogShow($"打开视图异常：{ex}", Core.Enum.LogLevel.Error, hostDialog: Core.Enum.PopUpType.Global);
            }
        }

        public DelegateCommand<TreeView> SelectedItemChanged => new DelegateCommand<TreeView>(sender =>
        {
            MenuItemModel menu = sender.SelectedItem as MenuItemModel;
            OpenView(menu);
        });

        /// <summary>
        /// 初始化菜单
        /// </summary>
        private void Init()
        {
            List<Type> types = new List<Type>();
            var dlls = AssemblyLoadContext.All;
            foreach (var dll in dlls)
            {
                foreach (var assemblie in dll.Assemblies)
                {
                    try
                    {
                        var parameter = assemblie.GetTypes().Where(t => t.IsClass && typeof(IModule).IsAssignableFrom(t) && typeof(AntMovement.WPF.Model.MenuModel).IsAssignableFrom(t)).ToList();
                        if (parameter.Count > 0)
                        {
                            AntMovement.WPF.Model.MenuModel menuModel = Activator.CreateInstance(parameter[0]) as AntMovement.WPF.Model.MenuModel;
                            menuModel.Childrens = new ObservableCollection<WPF.Model.MenuItemModel>();
                            menuModel.IsSystem = true;
                            menuAssemblyModels.Add(new MenuAssemblyModel()
                            {
                                MenuName = menuModel.TitleLang,
                                Model = menuModel,
                                MenuAssembly = assemblie
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                        _containerExtension.Resolve<IDialogHost>().DialogShow($"插件加载异常：{ex}", Core.Enum.LogLevel.Error);
                        return;
                    }
                }
            }
        }

        private void UpdateMenu()
        {
            Menus.Clear();
            List<MenuModel> menus = new List<MenuModel>();
            foreach (var item in menuAssemblyModels)
            {
                var types = item.MenuAssembly.GetTypes().Where(t => t.IsClass && t.GetCustomAttribute<MenuAttribute>() != null).ToList();
                List<WPF.Model.MenuItemModel> menuItems = new List<MenuItemModel>();
                foreach (var view in types)
                {
                    var attribute = view.GetCustomAttribute<MenuAttribute>();
                    menuItems.Add(new WPF.Model.MenuItemModel()
                    {
                        Index = attribute.Index,
                        Name = attribute.RegionName,
                        IsSystem = true,
                        View = view,
                        ViewModel = item.MenuAssembly.GetType($"{view.Namespace.Replace("Views", "ViewModels")}.{view.Name}ViewModel"),
                    });
                }
                menuItems.Sort((x, y) => x.CompareTo(y));
                menus.Add(new MenuModel()
                {
                    Childrens = new ObservableCollection<MenuItemModel>(menuItems),
                    Index = item.Model.Index,
                    IsSystem = true,
                    PackIcon = item.Model.PackIcon,
                    Title = item.Model.Title,
                    TitleLang = item.Model.TitleLang,
                });
            }
            menus.Sort((x, y) => x.CompareTo(y));
            foreach (var item in menus)
            {
                Menus.Add(item);
            }
        }
    }
}
